package cn.jinjimi.app.bean;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import cn.jinjimi.framework.router.annotations.Direct;
import cn.jinjimi.framework.router.annotations.EventRoute;
import cn.jinjimi.framework.router.annotations.Route;
import cn.jinjimi.framework.router.impl.DirectRoute;

/**
 *
 * @author zhenhua
 * @date 17/9/18
 */

public class RouterService {
    /**
     *  原生界面的协议头
     */
    public static final String ROUTER_HEADER = "cn.jinjimi://";

    /**
     * 原生界面的协议头
     */
    public static final String ROUTER_HEADER_SHORT = "jjm://";

    /**
     *  路由表
     */
    public static final HashMap<String, Object> ROUTER_TABLE = new HashMap<>();

    public static final List<String> ROUTER_PARAM = new ArrayList<>();

    public static final String URL_LIMIT = "limit=1";

    public static final String ROUTER_WEB_ROUTER = "url";

    public static final String ROUTER_WEB_ROUTER_DIRECT = "direct";

    public static final List<String> LIMIT_TABLE = new ArrayList<>();

    static {
        ROUTER_PARAM.add(BundleKey.OUTCHANNEL);
        ROUTER_PARAM.add(BundleKey.SOURCE);

        loadRoutes();
    }

    /**
     * 解析类定义中的路由信息并添加到路由表
     * @param routes
     * @throws IllegalAccessException
     */
    public static void loadRoutes(Class<?> routes) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        Field[] fields = routes.getDeclaredFields();
        for(Field field:fields){
            Annotation annotation = field.getAnnotation(Route.class);
            Annotation eventAnnotation = field.getAnnotation(EventRoute.class);
            Annotation directAnnotation = field.getAnnotation(Direct.class);

            if(annotation==null
                    && eventAnnotation==null
                    && directAnnotation==null){
                continue;
            }

            String path = (String)field.get(null);

            if(annotation!=null){
                Route route = (Route)annotation;
                ROUTER_TABLE.put(path, route.activity().getName());
                if(route.limit()){
                    LIMIT_TABLE.add(path);
                }
            }

            if(eventAnnotation!=null){
                EventRoute event = (EventRoute)eventAnnotation;
                Class<?> eventClass = event.value();
                Constructor<?> constructor = eventClass.getConstructor();
                ROUTER_TABLE.put(path, constructor.newInstance());
                if(event.limit()){
                    LIMIT_TABLE.add(path);
                }
            }

            if(directAnnotation!=null){
                Direct direct = (Direct)directAnnotation;
                if(direct.value().length()>0){
                    ROUTER_TABLE.put(path, new DirectRoute(direct.value()));
                }
                if(direct.limit()){
                    LIMIT_TABLE.add(path);
                }

            }

        }
    }

    public static void loadRoutes(){
        try {
            loadRoutes(RouterConstants.class);
        } catch (IllegalAccessException e) {
            //e.printStackTrace();
        } catch (NoSuchMethodException e) {
            //e.printStackTrace();
        } catch (InstantiationException e) {
            //e.printStackTrace();
        } catch (InvocationTargetException e) {
            //e.printStackTrace();
        }
    }
}
